package com.kitty.game.activity.service.shidao;

import com.kitty.common.cache.RedisService;
import com.kitty.common.core.SchedulerManager;
import com.kitty.common.utils.ConcurrentHashSet;
import com.kitty.common.utils.DecodeSendMessage;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.ServerService;
import com.kitty.game.activity.ActivityDataPool;
import com.kitty.game.activity.model.product.ShiDaoReward;
import com.kitty.game.activity.model.product.ShiDaoSet;
import com.kitty.game.activity.model.user.*;
import com.kitty.game.activity.service.ActivityHandler;
import com.kitty.game.chat.service.ChatService;
import com.kitty.game.config.LoginServer;
import com.kitty.game.config.NPC;
import com.kitty.game.config.TaskSet;
import com.kitty.game.confirm.model.EnterShiDaoConfirm;
import com.kitty.game.enter.ReqTelePort;
import com.kitty.game.enter.RespGeneralNotify;
import com.kitty.game.enter.TitleInfo;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.mail.model.Mail;
import com.kitty.game.map.MapDataPool;
import com.kitty.game.map.model.GroupMapParam;
import com.kitty.game.npc.model.NpcButton;
import com.kitty.game.player.PlayerService;
import com.kitty.game.rank.model.Range;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.AccountService;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.shidao.KuafuShidaoService;
import com.kitty.game.shidao.RespShidaoScore;
import com.kitty.game.shidao.message.RespShidaoGloryHistory;
import com.kitty.game.shidao.message.vo.LevelInfo;
import com.kitty.game.shidao.message.vo.ShidaoMember;
import com.kitty.game.shidao.message.vo.TimeInfo;
import com.kitty.game.task.model.product.TaskType;
import com.kitty.game.task.service.taskHandler.TaskHelper;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.tongtianta.BallotInfo;
import com.kitty.game.tongtianta.RespBallotResult;
import com.kitty.game.tongtianta.RespTeamBallot;
import com.kitty.game.utils.*;
import com.kitty.game.welfare.model.CommonFetchedData;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.task.ThreadLocalUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.http.Request;
import org.nutz.http.Sender;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.function.Consumer;
/*世道配置类*/
@Component
@Slf4j
public class ShiDaoHandler extends ActivityHandler {
    @Autowired
    protected TeamService teamService;
    @Autowired
    ChatService chatService;

    @Getter
    private ShiDaoSet shiDaoSet;
    @Getter
    @Setter
    private ShiDaoData shiDaoData;
    @Autowired
    ServerService serverService;
    @Autowired
    RedisService redisService;

    /**
     * 等级段
     */
    private List<Range<Short>> levelRanges = new ArrayList<>();

    /**
     * 最小等级
     */
    private static final int MIN_LEVEL = 60;
    /**
     * 最少组队人数
     */
    //private static final int MIN_TEAM_COUNT = 1;
    private static final int MAPID = Const.SHIDAO_MAPID;
    private static final int MAP_X = 20;
    private static final int MAP_Y = 20;
    private static final int EXIT_MAPID = 5000;
    private static final int EXIT_X = 95;
    private static final int EXIT_Y = 64;

    /**
     * 试道大会奖励任务ID
     */
    public static final int REWARD_TASKID = 95;

    private ScheduledFuture scheduledFuture;

    /**
     * 时间格式 2019-07-28-20:50:00
     */
    private static final String TIME_FORMAT_PATTERN = "yyyy-MM-dd-HH:mm:ss";
    private static final String FIGHT_LEVEL_NOT_ENOUGH = "等级达到70级方可参加试道大会。[离开]";
    private static final String NOT_SIGNUP_TIME = "现在还不是报名时间，#Y{0}#n级别试道大会下一场将于#R{1}#n开始报名。[离开]";
    /**
     * 报名时间结束
     */
    private static final String SIGNUP_END = "试道大会正在举行中不可报名参加[离开]";
    private static final String TEAM_COUNT_NOT_ENOUGH = "队伍不足一人无法参加试道大会。[离开]";
    private static final String LEVEL_NOT_SAME = "#Y{0}#n的等级不符，无法参加#Y{1}#n级别的试道大会。[离开]";
    private static final String MEMBER_LEAVE_MONMENT = "#Y{0}#n暂离，无法参加试道大会。[离开]";
    private static final String ENTER_SHI_DAO_MESSAGE = "队长申请进入试道场，是否同意？";

    private static final String REQUEST_JOIN_LIMIT = "当前地图无法申请";
    private static final String INVITE_JOIN_LIMIT = "当前地图无法邀请";
    private static final String ACCEPT_JOIN_LIMIT = "该地图无法操作申请队员";
    private static final String COMPETE_PK_LIMIT = "你现在不能与人切磋。";
    private static final String LEAVE_MONMENT = "试道场地中无法暂离，确认暂离将会离开队伍。";

    private static final String BALLOT_TITLE = "进入试道场投票";
    private static final String GLORY_HISTORY_EMPTY = "暂无数据";

    private static final String SIGNUP_CONTENT = "英雄侠士竞风豪，欲与天公试比高，万众瞩目的试道大会又要开始啦。[我要报名参加试道大会/" + NpcButton.SHIDAO_DAHUI_SIGNUP_CONFIRM.getKey() + "]";
    private static final String ENTER_MAP_CONTENT = "英雄侠士竞风豪，欲与天公试比高，万众瞩目的试道大会又要开始啦。[我要进入试道大会场地/" + NpcButton.SHIDAO_DAHUI_ENTER_MAP.getKey() + "]";

    private static final String NOTICE_CONTENT = "#R试道申请人#n：试道大会分月道和总道，本周举行试道大会为#Y{0}#n。望各位道友准点参加。";

    public static final String REWARD_CONTENT = "#Y{0}#n赢得了#Y{1}#n的#Y{2}#n级别试道大会#R第{3}名#n，获得了大量道具大量数值和{4}的奖励！";

    private int startH = 20;
    private int startM = 50;

    @PostConstruct
    public void init() {
        MapDataPool.MAP_KEY_GENERATERS.put(MAPID, (role -> getLevelRange(role)));
        initRange();
    }

    /**
     * 初始化等级段
     */
    private void initRange() {
        levelRanges.add(new Range((short) 70, (short) 79));
        levelRanges.add(new Range((short) 80, (short) 89));
        levelRanges.add(new Range((short) 90, (short) 99));
        levelRanges.add(new Range((short) 100, (short) 109));
        levelRanges.add(new Range((short) 110, (short) 119));
        levelRanges.add(new Range((short) 120, (short) 129));
        levelRanges.add(new Range((short) 130, (short) 139));
        levelRanges.add(new Range((short) 140, (short) 149));
        levelRanges.add(new Range((short) 150, (short) 159));
        levelRanges.add(new Range((short) 160, (short) 169));
        levelRanges.add(new Range((short) 170, (short) 179));



    }

    /**
     * 为试道大会做准备工作
     */
    public void prepareOnceShiDao() {
        initShiDaoData();
        log.error("时间初始化=={}=={}=={}"
                , (shiDaoData.getStartTime().getTimeInMillis() - shiDaoData.getSignupTime().getTimeInMillis())
                , (shiDaoData.getMonsterEndTime().getTimeInMillis() - shiDaoData.getStartTime().getTimeInMillis())
                , (shiDaoData.getEndTime().getTimeInMillis() - shiDaoData.getMonsterEndTime().getTimeInMillis())
        );
        addCheckJob();
        addStartJob();
        addMonsterEndJob();
        addEndJob();
    }

    private boolean isopen() {
        String aaaa = DateUtils.dayForWeek(new Date());
        if (!aaaa.equals("3") && !aaaa.equals("5")) {
            return false;
        }
        return true;
    }

    /**
     * 初始化试道大会数据
     */
    private void initShiDaoData() {
        rangeHandle(levelRange -> clear(levelRange));

        ShiDaoData shiDaoData = new ShiDaoData();
        initTime(shiDaoData);
        this.shiDaoData = shiDaoData;
        ShiDaoSet shiDaoSet = new ShiDaoSet();
        this.shiDaoSet = new ShiDaoSet();
    }

    private void clear(String levelRange) {
        ConcurrentHashSet<Integer> roleIds = SpringUtils.getMapService().getRoleIds(new GroupMapParam(levelRange), Const.SHIDAO_MAPID);
        if (roleIds != null) {
            log.error("上次试道遗留的角色ID信息=={}=={}", levelRange, Json.toJson(roleIds, JsonFormat.compact()));
            roleIds.clear();
        }
    }

    /**
     * 初始化时间
     */
    public void initTime(ShiDaoData shiDaoData) {
        //测试代码        curHour24 = calendar.get(calendar.HOUR_OF_DAY);
        Calendar calendarStart = Calendar.getInstance();
        calendarStart.setTime(new Date());
        calendarStart.set(Calendar.HOUR_OF_DAY, startH);
        calendarStart.set(Calendar.MINUTE, startM);
        calendarStart.set(Calendar.SECOND, 0);
        {
            shiDaoData.setSignupTime(get(calendarStart));
        }
        int signupTime = Integer.parseInt(DataCache.REDIS_DATA.get("shidao_signuptime"));
        if (serverService.getServer().getId() != 10000) {
            calendarStart.add(Calendar.MINUTE, signupTime);
        } else {
            calendarStart.add(Calendar.MINUTE, signupTime*3);
        }

        {
            shiDaoData.setStartTime(get(calendarStart));
        }
        int monsterTime = Integer.parseInt(DataCache.REDIS_DATA.get("shidao_monstertime"));
        if (serverService.getServer().getId() != 10000) {
            calendarStart.add(Calendar.MINUTE, monsterTime);
        } else {
            calendarStart.add(Calendar.MINUTE, monsterTime);
        }
        {
            shiDaoData.setMonsterEndTime(get(calendarStart));
        }
        int pkTime = Integer.parseInt(DataCache.REDIS_DATA.get("shidao_pktime"));
        calendarStart.add(Calendar.MINUTE, pkTime);
        {
            shiDaoData.setEndTime(get(calendarStart));
        }
        int durationTime = (int) ((shiDaoData.getMonsterEndTime().getTimeInMillis() - shiDaoData.getStartTime().getTimeInMillis()) / TimeUtil.ONE_SECOND);
        shiDaoData.setMonsterDurationTime(durationTime);

        durationTime = (int) ((shiDaoData.getEndTime().getTimeInMillis() - shiDaoData.getMonsterEndTime().getTimeInMillis()) / TimeUtil.ONE_SECOND);
        shiDaoData.setPkDurationTime(durationTime);
        /**双数日期为月道行试道大会*/
        boolean isMonthTao = isMonth(shiDaoData.getEndTime());
        shiDaoData.setMonthTao(isMonthTao);
        if (isMonthTao) {
            int time = (int) (shiDaoData.getEndTime().getTimeInMillis() / TimeUtil.ONE_SECOND);
            if (!DataCache.MONTH_SHI_DAO_TIMES.contains(time)) {
                DataCache.MONTH_SHI_DAO_TIMES.add(time);
            }
        }

        log.info("初始化试道大会|报名时间:{}, 开始时间:{}, 挑战元魔结束时间:{}, 整个结束时间:{}, 月道行试道大会:{}",
                TimeUtil.formatDate(shiDaoData.getSignupTime().getTime(), TimeUtil.DEFAULT_DATE_FORMAT),
                TimeUtil.formatDate(shiDaoData.getStartTime().getTime(), TimeUtil.DEFAULT_DATE_FORMAT),
                TimeUtil.formatDate(shiDaoData.getMonsterEndTime().getTime(), TimeUtil.DEFAULT_DATE_FORMAT),
                TimeUtil.formatDate(shiDaoData.getEndTime().getTime(), TimeUtil.DEFAULT_DATE_FORMAT),
                isMonthTao);
    }

    private Calendar get(Calendar calendarStart) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(calendarStart.getTime());
        calendar.set(Calendar.HOUR_OF_DAY, calendarStart.get(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendarStart.get(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, 0);
        return calendar;
    }

    /**获得试道大会那天的Calendar对象*/
//    private Calendar getMatchCalendar() {
//        Calendar calendar = Calendar.getInstance();
//
//        int totalDayOfWeek = shiDaoSet.getTotalDayOfWeek();
//        int monthDayOfWeek = shiDaoSet.getMonthDayOfWeek();
//
//        Date startDate = TimeUtil.parseTime(shiDaoSet.getStartTime());
//        Calendar tempCalendar = Calendar.getInstance();
//        tempCalendar.setTime(startDate);
//        Calendar startCalendar = Calendar.getInstance();
//        startCalendar.set(Calendar.HOUR_OF_DAY, tempCalendar.get(Calendar.HOUR_OF_DAY));
//        startCalendar.set(Calendar.MINUTE, tempCalendar.get(Calendar.MINUTE));
//        startCalendar.set(Calendar.SECOND, tempCalendar.get(Calendar.SECOND));
//
//        int day = calendar.get(Calendar.DAY_OF_WEEK);
//        if ((day == totalDayOfWeek || day == monthDayOfWeek) && calendar.before(startCalendar)) {
//            return calendar;
//        }
//
//        for (int i=0; i<7; i++) {
//            calendar.add(Calendar.DAY_OF_YEAR, 1);
//            day = calendar.get(Calendar.DAY_OF_WEEK);
//            if (day == totalDayOfWeek || day == monthDayOfWeek) {
//                break;
//            }
//        }
//        return calendar;
//    }
//
//    private Calendar getTimeCalendar(Calendar matchCalendar, String datestr) {
//        Calendar tempCalendar = Calendar.getInstance();
//        Date date = TimeUtil.parseTime(datestr);
//        tempCalendar.setTime(date);
//
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(matchCalendar.getTime());
//        calendar.set(Calendar.HOUR_OF_DAY, tempCalendar.get(Calendar.HOUR_OF_DAY));
//        calendar.set(Calendar.MINUTE, tempCalendar.get(Calendar.MINUTE));
//        calendar.set(Calendar.SECOND, tempCalendar.get(Calendar.SECOND));
//
//        return calendar;
//    }

    /**
     * 添加定时检测的定时任务
     */
    private void addCheckJob() {
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(shiDaoData.getStartTime().getTime());
//        calendar.add(Calendar.HOUR_OF_DAY, -1);
        long initialDelay = shiDaoData.getStartTime().getTimeInMillis() - System.currentTimeMillis();
        log.error("添加定时检测的定时任务==={}", initialDelay);
        /**启动定时检测*/
        try {
            if (scheduledFuture != null) {
                scheduledFuture.cancel(false);
            }
        } catch (Exception e) {
            log.error("定时器关闭==", e);
        }
        scheduledFuture = SchedulerManager.getInstance().scheduleAtFixedRate(() -> checkInterval(), initialDelay, TimeUtil.ONE_MINUTE);
    }

    /**
     * 添加试道大会开始的定时任务
     */
    private void addStartJob() {
        long initialDelay = shiDaoData.getStartTime().getTimeInMillis() - System.currentTimeMillis();
        log.error("添加试道大会开始的定时任务==={}", initialDelay);
        SchedulerManager.getInstance().schedule(() -> SpringUtils.getBean(ShiDaoMonsterHandler.class).start(), initialDelay);
    }

    /**
     * 添加试道大会挑战元魔结束的定时任务
     */
    private void addMonsterEndJob() {
        long initialDelay = shiDaoData.getMonsterEndTime().getTimeInMillis() - System.currentTimeMillis();
        log.error("添加试道大会挑战元魔结束的定时任务==={}", initialDelay);
        SchedulerManager.getInstance().schedule(() -> {
            SpringUtils.getBean(ShiDaoMonsterHandler.class).end();
            SpringUtils.getBean(ShiDaoPKHandler.class).start();
        }, initialDelay);
    }

    /**
     * 添加试道大会结束的定时任务
     */
    private void addEndJob() {
        long initialDelay = shiDaoData.getEndTime().getTimeInMillis() - System.currentTimeMillis();
        log.error("添加试道大会结束的定时任务==={}", initialDelay);
        SchedulerManager.getInstance().schedule(() -> end(), initialDelay);
    }

    private void end() {
        SpringUtils.getBean(ShiDaoPKHandler.class).end();
        SpringUtils.getBean(KuafuShidaoService.class).content = "";
        if (scheduledFuture != null) {
            scheduledFuture.cancel(Boolean.FALSE);
        }
    }

    public String getLevelRange(Range range) {
        return range.getMin() + "-" + range.getMax();
    }

    /**
     * 找到角色对应的分段
     */
    public String getLevelRange(Role role) {
        short roleLevel = role.getLevel();
        Range<Short> range = getRange(roleLevel);
        if (range != null) {
            return getLevelRange(range);
        }
        return null;
    }

    public Range getRange(short roleLevel) {
        for (Range<Short> range : levelRanges) {
            if (roleLevel >= range.getMin() && roleLevel <= range.getMax()) {
                return range;
            }
        }
        return null;
    }

    public void rangeHandle(Consumer<String> consumer) {
        for (Range<Short> range : levelRanges) {
            String levelRange = getLevelRange(range);
            consumer.accept(levelRange);
        }
    }

    private void checkInterval() {
        Calendar calendar = Calendar.getInstance();
        /**PK阶段*/
        if (shiDaoData.getStage() != ShiDaoData.STAGE_PK) {
            SpringUtils.getBean(ShiDaoMonsterHandler.class).checkSystemMessage(calendar);
        } else {
            SpringUtils.getBean(ShiDaoPKHandler.class).checkSystemMessage(calendar);
        }
    }

    public void sendRespShidaoScore(Role role) {
        RespShidaoScore respShidaoScore = getRespShidaoScore(role);
        MessagePusher.pushMessage(role, respShidaoScore);
    }

    public RespShidaoScore getRespShidaoScore(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        if (team == null) {
            return null;
        }

        RespShidaoScore respShidaoScore = new RespShidaoScore();
        respShidaoScore.setStageId(shiDaoData.getStage());
        /*
        * 准备阶段倒计时
        */
        respShidaoScore.setStartTime(Math.toIntExact(shiDaoData.getStartTime().getTimeInMillis() / 1000));
        switch (shiDaoData.getStage()) {
            case ShiDaoData.STAGE_READY:
                break;
            case ShiDaoData.STAGE_MONSTER:   /**挑战元魔阶段*/
                ShiDaoMonsterData shiDaoMonsterData = shiDaoData.getMonsterDataMap().get(team.getId());
                if (shiDaoMonsterData != null) {
                    respShidaoScore.setMonsterPoint((short) (shiDaoMonsterData.getMonsterScore() * teamService.getTeamCount(team)));
                }
                respShidaoScore.setStage1_duration_time(shiDaoData.getMonsterDurationTime());
                respShidaoScore.setStage2_duration_time(shiDaoData.getPkDurationTime());
                break;
            /**PK阶段*/
            case ShiDaoData.STAGE_PK:
                ShiDaoPKData shiDaoPKData = shiDaoData.getPkDataMap().get(team.getId());
                if (shiDaoPKData != null) {
                    respShidaoScore.setTotalScore(shiDaoPKData.getTotalScore());
                    respShidaoScore.setPkValue(shiDaoPKData.getPkValue());
                    respShidaoScore.setRank(shiDaoPKData.getRank());
                }
                respShidaoScore.setStage1_duration_time(shiDaoData.getMonsterDurationTime());
                respShidaoScore.setStage2_duration_time(shiDaoData.getPkDurationTime());
                break;
        }
        return respShidaoScore;
    }

    public void sendNpcContent(Role role, NPC bossNpc) {
        String content = getNpcContent(role, bossNpc);
        SpringUtils.getNpcService().sendNpcContent(role, bossNpc, content);
    }

    /**
     * 进入试道大会地图
     */
    public void enterShiDaoMap(Role role, NPC bossNpc) {
        String content = getNpcContent(role, bossNpc);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, bossNpc, content);
        }
        int minTeamMembetCount = Integer.parseInt(DataCache.REDIS_DATA.get("shidao_minteam_count"));
        if (minTeamMembetCount == 1 && teamService.getTeamCount(role) == 1) {
            doEnterShiDaoMap(role);
        } else {
            startBallot(role);
        }
    }

    public String canEnter(Role role) {
        /**等级不足*/
        if (role.getLevel() < 60) {
            return FIGHT_LEVEL_NOT_ENOUGH;
        }

        String levelRange = getLevelRange(role);
        Calendar calendar = Calendar.getInstance();
        /**未到报名时间*/
        ShiDaoData shiDaoData = getShiDaoData();
        if (shiDaoData == null) {
            return "时间还没到，请关注系统公告[离开]";
        }
        if (calendar.before(shiDaoData.getSignupTime())) {
            return MessageFormat.format(NOT_SIGNUP_TIME, levelRange, TimeUtil.formatDate(shiDaoData.getSignupTime().getTime(), TIME_FORMAT_PATTERN));
        }

        /**试道大会已经开始*/
        if (calendar.after(shiDaoData.getStartTime())) {
            return SIGNUP_END;
        }

        /**人数少于3人*/
        int teamCount = teamService.getTeamCount(role);
        int minTeamMembetCount = Integer.parseInt(DataCache.REDIS_DATA.get("shidao_minteam_count"));
        if (teamCount < minTeamMembetCount) {
            return TEAM_COUNT_NOT_ENOUGH;
        }

        /**队员等级段是否相同*/
        Team team = teamService.getTeam(role.getRoleId());
        String names = teamService.checkMember(team, memberRole -> !levelRange.equals(getLevelRange(memberRole)));
        if (names != null) {
            return MessageFormat.format(LEVEL_NOT_SAME, names, levelRange);
        }

        names = teamService.getNotInTeam(team);
        if (names != null) {
            return MessageFormat.format(MEMBER_LEAVE_MONMENT, names, levelRange);
        }
        return null;
    }

    public String getNpcContent(Role role, NPC bossNpc) {
        String content = canEnter(role);
        if (content != null) {
            return content;
        }

        if (role.getTalk().popChooseParam("shidao_dahui_enter_map") != null) {
            return null;
        }

        if (role.getTalk().popChooseParam("shidao_dahui_signup_confirm") != null) {
            role.getTalk().pushChooseParam("shidao_dahui_enter_map", true);
            return ENTER_MAP_CONTENT;
        }

        role.getTalk().pushChooseParam("shidao_dahui_signup_confirm", true);
        return SIGNUP_CONTENT;
    }

    /**
     * 进入试道大会地图
     */
    public void doEnterShiDaoMap(Role role) {
        ReqTelePort reqTelePort = new ReqTelePort();
        reqTelePort.setMapId(MAPID);
        reqTelePort.setX(MAP_X);
        reqTelePort.setY(MAP_Y);
        SpringUtils.getMapService().changeMap(role, reqTelePort);

        /**需要在进入地图后发送，所以加到玩家的处理线程最后*/
        ThreadLocalUtil.addLocalTask(role, () -> sendRespShidaoScore(role));

        log.info("进入试道场=={}=={}", role.getGid(), role.getName());
    }


    public void leave(Role role) {
        if (shiDaoData != null && shiDaoData.getEndTime().getTimeInMillis() > System.currentTimeMillis()) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("试道尚未结束！"));
            return;
        }
//        try {
//            shiDaoData.getRolesLeave().add(role.getRoleId());
//        }catch (Exception e){
//        }
        leaveShiDaoMap(role);
        MessagePusher.pushMessage(role, new RespNotifyMiscEx("主动离开试道场，将不能获得试道名次！！！"));
    }

    public boolean enterKuafu() {
        if (shiDaoData == null) {
            return false;
        }
        if (shiDaoData.getEndTime().getTimeInMillis() < System.currentTimeMillis()) {
            return false;
        }
        return true;
    }


    /**
     * 离开试道大会地图
     */
    public void leaveShiDaoMap(Role role) {
        if (role == null) {
            return;
        }
        log.info("离开试道场111=={}=={}", role.getGid(), role.getName());
        /**不在试道大会地图不处理*/
        if (role.getPos().getMapId() != Const.SHIDAO_MAPID) {
            return;
        }
        Team team = teamService.getTeam(role.getRoleId());
        if (team != null) {
            ArrayList<Member> arrayList = new ArrayList<>(team.getList());
            for (Member member : arrayList) {
                IoSession session = SessionUtils.getSession(member.getRoleId());
                if (session == null) {
                    return;
                }
                Role tempRole = SessionUtils.getRoleBySession(session);
                if (tempRole == null) {
                    continue;
                }
                RoleService roleService = SpringUtils.getRoleService();
                if (serverService.getServer().getId() != 10000) {
                    {
                        Mail mail = SpringUtils.getMailService().createMail("试道大会参与奖励", "试道奖励", 7 * TimeUtil.ONE_DAY);
                        ArrayList<NutMap> maps = new ArrayList<>();
                        String reward = DataCache.REDIS_DATA.get("shidao_reward_4");
                        if(StringUtils.isNotEmpty(reward)){
                            for (String s : reward.split("\\+")) {
                                NutMap nutMap = DecodeSendMessage.buildSendRewardMessage(s);
                                maps.add(nutMap);
                            }
                            mail.getDatas().addAll(maps);
                            SpringUtils.getMailService().sendNewMail(role, mail);
                        }
                    }
                } else {
                    // 离开跨服试道场，发放参与奖
                    NutMap nutMap = new NutMap();
                    nutMap.put("name", tempRole.getName());
                    nutMap.put("type", "道行盒子");
                    nutMap.put("count", 20);
                    NutMap param = new NutMap();
                    param.put("content", Json.toJson(nutMap, JsonFormat.compact()));
                    Request request = Request.create(serverService.getLoginServerUrl() + "/game/enterReward", Request.METHOD.GET).setParams(param);
                    Sender.create(request).setTimeout(2000).send().getContent();
                    roleService.addRechargeScore(role, 60);
                    log.error("发放参与奖=={}=={}=={}", tempRole.getRoleId(), tempRole.getName(), Json.toJson(nutMap, JsonFormat.compact()));
                }
            }
        } else {
            if (serverService.getServer().getId() != 10000) {
                {
                    Mail mail = SpringUtils.getMailService().createMail("试道大会参与奖励", "试道奖励", 7 * TimeUtil.ONE_DAY);
                    ArrayList<NutMap> maps = new ArrayList<>();
                    String reward = DataCache.REDIS_DATA.get("shidao_reward_4");
                    if(StringUtils.isNotEmpty(reward)){
                        for (String s : reward.split("\\+")) {
                            NutMap nutMap = DecodeSendMessage.buildSendRewardMessage(s);
                            maps.add(nutMap);
                        }
                        mail.getDatas().addAll(maps);
                        SpringUtils.getMailService().sendNewMail(role, mail);
                    }
                }
            } else {
                // 离开跨服试道场，发放参与奖
                NutMap nutMap = new NutMap();
                nutMap.put("name", role.getName());
                nutMap.put("type", "道行盒子");
                nutMap.put("count", 20);
                NutMap param = new NutMap();
                param.put("content", Json.toJson(nutMap, JsonFormat.compact()));
                Request request = Request.create(serverService.getLoginServerUrl() + "/game/enterReward", Request.METHOD.GET).setParams(param);
                Sender.create(request).setTimeout(2000).send().getContent();
                log.error("发放参与奖=={}=={}=={}", role.getRoleId(), role.getName(), Json.toJson(nutMap, JsonFormat.compact()));
            }
        }


        /**不需要检测能否切换地图*/
        role.pushTempCache(Const.NOT_CHECK_CHANGE_MAP, true);

        ReqTelePort reqTelePort = new ReqTelePort();
        if (serverService.getServer().getId() != 10000) {
            reqTelePort.setMapId(EXIT_MAPID);
            reqTelePort.setX(EXIT_X);
            reqTelePort.setY(EXIT_Y);
        } else {
            KuafuShidaoService kuafuShidaoService = SpringUtils.getBean(KuafuShidaoService.class);
            reqTelePort.setMapId(kuafuShidaoService.mapId);
            reqTelePort.setX(kuafuShidaoService.x);
            reqTelePort.setY(kuafuShidaoService.y);
        }

        SpringUtils.getMapService().changeMap(role, reqTelePort);
        log.info("离开试道场=={}=={}", role.getGid(), role.getName());
    }

    /**
     * 是否可以申请组队
     */
    public boolean isRequestJoinTeam(Role role, Team team) {
        if (isInShiDaoMap(role)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(REQUEST_JOIN_LIMIT));
            return false;
        }

        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        if (isInShiDaoMap(leaderRole)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(REQUEST_JOIN_LIMIT));
            return false;
        }

        return true;
    }

    /**
     * 是否可以邀请组队
     */
    public boolean isInviteJoinTeam(Role role, int inviteRoleId) {
        if (isInShiDaoMap(role)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(INVITE_JOIN_LIMIT));
            return false;
        }


        Role invitRole = SpringUtils.getRoleService().getOnlinePlayer(inviteRoleId);
        if (isInShiDaoMap(invitRole)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(INVITE_JOIN_LIMIT));
            return false;
        }

        return true;
    }

    public boolean isAcceptJoinTeam(Role role, int joinRoleId) {
        if (isInShiDaoMap(role)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(ACCEPT_JOIN_LIMIT));
            return false;
        }
        Role joinRole = SpringUtils.getRoleService().getOnlinePlayer(joinRoleId);
        if (isInShiDaoMap(joinRole)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(ACCEPT_JOIN_LIMIT));
            return false;
        }

        return true;
    }

    /**
     * 在试道大会暂离确认
     */
    public boolean leaveMonmentConfirm(Role role) {
        if (isInShiDaoMap(role)) {
//            role.setConfirm(new LeaveTeamConfirm());
//
//            RespConfirm respConfirm = new RespConfirm();
//            respConfirm.setTips(LEAVE_MONMENT);
//            respConfirm.setConfirm_type("");
//            MessagePusher.pushMessage(role, respConfirm);
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("试道场景内，不能暂离！！！"));
            return false;
        }

        return true;
    }

    /**
     * 是否在试道场
     */
    public boolean isInShiDaoMap(Role role) {
        return SpringUtils.getMapService().isInMap(role, MAPID);
    }

    /**
     * 在试道场离开队伍后
     */
    public void doAfterLeaveTeam(Role role, Team team) {
        if (!isInShiDaoMap(role)) {
            return;
        }

        /**离开队伍的人离开试道场*/
        leaveShiDaoMap(role);

//        /**队伍成员数量少于最小数量时，整个队伍离开试道场*/
//        if (teamService.getTeamCount(team) < shiDaoSet.getMinTeamMemberCount()) {
//            Role leaderRole = SpringUtils.getPlayerService().getPlayerBy(team.getLeaderRoleId());
//            if (leaderRole != null) {
//                leaveShiDaoMap(leaderRole);
//            }
//        }
    }

    /**
     * 是否可以切磋竞技
     */
    public boolean isCompetePK(Role role, Role pkRole) {
        if (isInShiDaoMap(role)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(COMPETE_PK_LIMIT));
            return false;
        }

        if (isInShiDaoMap(pkRole)) {
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(COMPETE_PK_LIMIT));
            return false;
        }

        return true;
    }

    /**
     * 发起投票
     */
    public void startBallot(Role role) {
        if (teamService.isInTeam(role)) {
            /**只有队长能操作*/
            if (teamService.isTeamLeader(role) == false) {
                return;
            }

            Map<Integer, Short> ballotResults = new HashMap<>();
            role.setConfirm(new EnterShiDaoConfirm(ballotResults));
            Team team = teamService.getTeam(role.getRoleId());
            teamService.memberHandle(team, (Role memberRole) -> {
                ballotResults.put(memberRole.getRoleId(), Const.BALLOT_TYPE_UN_OP);
            });
            ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

            RespTeamBallot respTeamBallot = new RespTeamBallot();
            respTeamBallot.setTeamLeader(teamService.isTeamLeader(role));
            respTeamBallot.setMsg(ENTER_SHI_DAO_MESSAGE);
            respTeamBallot.setCurrTime(new Long(new Date().getTime() / 1000).intValue() + 30);
            respTeamBallot.setTitle(BALLOT_TITLE);
            teamService.pushMessage(role, respTeamBallot);

            RespBallotResult respBallotResult = getRespBallotResult(role);
            teamService.pushMessage(role, respBallotResult);
            //固定队
            fixedTeamAutoAgreen(role,team);
        }
    }

    /**
     * 投票。固定队开启自动同意投票
     */
    public void fixedTeamAutoAgreen(Role LeaderRole,Team team){
        //取队长固定队ID
        String fixedTeamId = LeaderRole.getFixedTeam();
        if(StringUtils.isNotEmpty(fixedTeamId)){
            for (Member member : team.getList()) {
                Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(member.getUid());
                if(!teamService.isTeamLeader(member.getRoleId())){
                    //如果是一个固定队
                    if(fixedTeamId.equals(memberRole.getFixedTeam())){
                        //自动同意
                        ballotAgree(memberRole);
                        MessagePusher.pushMessage(memberRole, new RespMsg("你开启了固定队伍特权1，参与试道#R投票#n自动通过"));

                    }
                }
            }
        }

    }



    /**
     * 进入试道场投票不同意
     */
    public void ballotDisagree(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        EnterShiDaoConfirm enterShiDaoConfirm = (EnterShiDaoConfirm) leaderRole.getConfirm();
        Map<Integer, Short> ballotResults = enterShiDaoConfirm.getBallotResults();
        ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_DISAGREE);

        if (isAllOp(ballotResults)) {
            closeBallot(team);
        }

        RespBallotResult respBallotResult = getRespBallotResult(role);
        teamService.pushMessageToTeam(team, respBallotResult);
    }

    /**
     * 进入试道场投票同意
     */
    public void ballotAgree(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        EnterShiDaoConfirm enterShiDaoConfirm = (EnterShiDaoConfirm) leaderRole.getConfirm();

        Map<Integer, Short> ballotResults = enterShiDaoConfirm.getBallotResults();
        ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

        RespBallotResult respBallotResult = getRespBallotResult(role);
        teamService.pushMessageToTeam(team, respBallotResult);

        if (isAllOp(ballotResults)) {
            closeBallot(team);
        }

        /**所有人已经同意，则开始进入试道场*/
        boolean allAgree = true;
        for (short result : ballotResults.values()) {
            if (result != Const.BALLOT_TYPE_AGREEN) {
                allAgree = false;
            }
        }

        if (allAgree) {
            doEnterShiDaoMap(leaderRole);
        }
    }

    /**
     * 获得托票结果
     */
    private RespBallotResult getRespBallotResult(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Map<Integer, Short> ballotResults = null;
        if (team.isLeader(role.getRoleId())) {
            EnterShiDaoConfirm confirm = (EnterShiDaoConfirm) role.getConfirm();
            ballotResults = confirm.getBallotResults();
        } else {
            Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            EnterShiDaoConfirm confirm = (EnterShiDaoConfirm) leaderRole.getConfirm();
            ballotResults = confirm.getBallotResults();
        }

        ArrayList<BallotInfo> ballotInfos = new ArrayList<>();
        for (Map.Entry<Integer, Short> entry : ballotResults.entrySet()) {
            Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(entry.getKey());
            if (memberRole == null) {
                continue;
            }
            BallotInfo ballotInfo = new BallotInfo();
            ballotInfo.setName(memberRole.getName());
            ballotInfo.setType(entry.getValue());
            ballotInfos.add(ballotInfo);
        }
        RespBallotResult respBallotResult = new RespBallotResult();
        respBallotResult.setMeTime((short) -1);
        respBallotResult.setResultList(ballotInfos);

        return respBallotResult;
    }

    /**
     * 是否队伍所有成员已经操作
     */
    private boolean isAllOp(Map<Integer, Short> ballotResults) {
        boolean allOp = true;
        for (short result : ballotResults.values()) {
            if (result == Const.BALLOT_TYPE_UN_OP) {
                allOp = false;
            }
        }

        return allOp;
    }

    /**
     * 关闭投票
     */
    private void closeBallot(Team team) {
        RespGeneralNotify respGeneralNotify = new RespGeneralNotify();
        respGeneralNotify.setNotify((short) NotifyModules.NOTIFY_CLOSE_DLG); //关闭对话框
        respGeneralNotify.setValue("DugeonVoteDlg");
        teamService.pushMessageToTeam(team, respGeneralNotify);
    }

    /**
     * 查看试道大会王者榜
     */
    public void viewGloryHistory(Role role, NPC npc) {
        if (DataCache.SHI_DAO_GLORY_HISTORYS.size() == 0) {
            teamService.pushMessage(role, new RespNotifyMiscEx(GLORY_HISTORY_EMPTY));
            return;
        }

        RespShidaoGloryHistory respShidaoGloryHistory = getRespShidaoGloryHistory();
        teamService.pushMessage(role, respShidaoGloryHistory);
    }

    private RespShidaoGloryHistory getRespShidaoGloryHistory() {
        RespShidaoGloryHistory respShidaoGloryHistory = new RespShidaoGloryHistory();

        List<LevelInfo> levelInfoList = new ArrayList<>();
        for (Map.Entry<Short, Map<Integer, List<ShiDaoGloryRecord>>> entry : DataCache.SHI_DAO_GLORY_HISTORYS.entrySet()) {
            List<TimeInfo> timeInfoList = new ArrayList<>();
            for (Map.Entry<Integer, List<ShiDaoGloryRecord>> secEntry : entry.getValue().entrySet()) {

                List<ShidaoMember> memberList = new ArrayList<>();
                for (ShiDaoGloryRecord shiDaoGloryRecord : secEntry.getValue()) {
                    ShidaoMember shidaoMember = new ShidaoMember(shiDaoGloryRecord.isLeader(), shiDaoGloryRecord.getName(), shiDaoGloryRecord.getLevel(), shiDaoGloryRecord.getPolar(), shiDaoGloryRecord.getGid(), shiDaoGloryRecord.getIcon());
                    memberList.add(shidaoMember);
                }

                /**是否月道行试道*/
                boolean isMonth = DataCache.MONTH_SHI_DAO_TIMES.contains(secEntry.getKey()) ? true : false;
                TimeInfo timeInfo = new TimeInfo(secEntry.getKey(), isMonth, memberList);
                timeInfoList.add(timeInfo);
            }

            LevelInfo levelInfo = new LevelInfo(entry.getKey(), timeInfoList);
            levelInfoList.add(levelInfo);
        }

        respShidaoGloryHistory.setLevelInfoList(levelInfoList);

        return respShidaoGloryHistory;
    }

    public void loadCommon() {
        loadGloryHistory();
        loadMonthTimes();
        loadTopRecords();
    }

    /**
     * 加载试道大会王者榜
     */
    private void loadGloryHistory() {
        Dao dao = SpringUtils.getBean(Dao.class);
        List<ShiDaoGloryHistory> list = dao.query(ShiDaoGloryHistory.class, Cnd.NEW());
        for (ShiDaoGloryHistory shiDaoGloryHistory : list) {
            Map<Integer, List<ShiDaoGloryRecord>> map = DataCache.SHI_DAO_GLORY_HISTORYS.computeIfAbsent(shiDaoGloryHistory.getLevel(), k -> new ConcurrentHashMap<>());
            List<ShiDaoGloryRecord> records = map.computeIfAbsent(shiDaoGloryHistory.getTime(), k -> new ArrayList<>());
            records.addAll(shiDaoGloryHistory.getRecords());
        }
    }

    /**
     * 加载月试道大会时间
     */
    private void loadMonthTimes() {
        Dao dao = SpringUtils.getBean(Dao.class);
        CommonFetchedData roleOfflineData = dao.fetch(CommonFetchedData.class, CommonConst.month_shidao_times);
        if (roleOfflineData != null) {
            List<Integer> list = JsonUtils.string2Collection(roleOfflineData.getData(), ArrayList.class, Integer.class);
            if (list != null) {
                DataCache.MONTH_SHI_DAO_TIMES.addAll(list);
            }
        }
    }

    private void loadTopRecords() {
        Dao dao = SpringUtils.getBean(Dao.class);
        //RoleOfflineData roleOfflineData = dao.fetch(RoleOfflineData.class, "shidao_top_records");
        CommonFetchedData  roleOfflineData = dao.fetch(CommonFetchedData.class, CommonConst.shidao_top_records);
        if (roleOfflineData != null) {
            DataCache.SHI_DAO_TOP_RECORDS.clear();
            Map<Long, ShiDaoTopRecord> map = JsonUtils.string2Map(roleOfflineData.getData(), Long.class, ShiDaoTopRecord.class);
            DataCache.SHI_DAO_TOP_RECORDS.putAll(map);
        }
    }

    /**
     * 加载上一试道的角色uid列表
     */
    private List<Long> getPreviousTitleUids(String levelRange) {
        List<Long> list = new ArrayList<>();
        for (ShiDaoTopRecord shiDaoTopRecord : DataCache.SHI_DAO_TOP_RECORDS.values()) {
            if (levelRange.equals(shiDaoTopRecord.getLevelRange())) {
                list.add(shiDaoTopRecord.getUid());
            }
        }
        return list;
    }

    /**
     * 从传入map中获得对应数据
     */
    public void loadCommonSet(Map<String, String> commonSetMap) {
        loadReward(commonSetMap);

    }

    private void loadReward(Map<String, String> commonSetMap) {
        String value = commonSetMap.get("shidao_dahui_reward_set");
        List<ShiDaoReward> shiDaoRewards = Json.fromJsonAsList(ShiDaoReward.class, value);

        Map<Byte, ShiDaoReward> shiDaoRewardMap = new HashMap<>();
        for (ShiDaoReward shiDaoReward : shiDaoRewards) {
            shiDaoRewardMap.put(shiDaoReward.getRank(), shiDaoReward);
        }

        ActivityDataPool.shiDaoRewardMap = shiDaoRewardMap;
    }



    @Override
    public void handleFightEnd(FightEndEvent fightEndEvent) {

    }

    @Override
    public void handleLogin(Role role) {
        /**登录时如果在试道场且且试道已经结束*/
        if (isInShiDaoMap(role) && (shiDaoData == null || shiDaoData.getEndTime().getTimeInMillis() < System.currentTimeMillis())) {
            leaveShiDaoMap(role);
        }
        super.handleLogin(role);
    }

    /**
     * 获得最近的王者记录
     */
    private List<ShiDaoGloryRecord> getRecentShiDaoGloryRecords(String levelRange) {
        short level = Short.parseShort(levelRange.split("-")[0]);
        Map<Integer, List<ShiDaoGloryRecord>> map = DataCache.SHI_DAO_GLORY_HISTORYS.get(level);
        if (map == null) {
            return null;
        }

        ArrayList<Integer> list = new ArrayList<>(map.keySet());
        if (list.size() == 0) {
            return null;
        }

        /**最近时间的王者记录*/
        Collections.sort(list);
        Integer time = list.get(list.size() - 1);

        List<ShiDaoGloryRecord> records = map.get(time);
        if (records == null || records.size() == 0) {
            return null;
        }
        return records;
    }

    /**
     * 回收试道王者称号
     */
    public void takeBackTitle(String levelRange) {
        List<Long> titleUids = getPreviousTitleUids(levelRange);
        for (long uid : titleUids) {
            Role role = SpringUtils.getPlayerService().getPlayerBy(uid);
            if (role == null) {
                continue;
            }

            SpringUtils.getRoleService().delTitle(role, Const.TITLE_TYPE_SHIDAO);
        }
    }

    /**
     * 增加试道王者称号
     */
    public void addTitle(String levelRange, List<ShiDaoPKData> topList) {
        int size = 3;
        if (topList.size() < 3) {
            size = topList.size();
        }

        for (int i = 0; i < size; i++) {
            ShiDaoPKData shiDaoPKData = topList.get(i);
            for (Member member : shiDaoPKData.getMembers()) {
                long uid = Long.parseLong(member.getGid());
                Role role = SpringUtils.getPlayerService().getPlayerBy(uid);
                if (role == null) {
                    continue;
                }
                int rank = i + 1;
                String titleName = getTitleName(rank);
                if (titleName == null) {
                    continue;
                }
                if(rank == 1){
                    SpringUtils.getBean(RoleService.class).addAchieveScore(role,"602036");
                }
                SpringUtils.getRoleService().addTitle(role, new TitleInfo(Const.TITLE_TYPE_SHIDAO, titleName));
                ShiDaoTopRecord shiDaoTopRecord = new ShiDaoTopRecord(uid, rank, levelRange, false, role.getName());
                DataCache.SHI_DAO_TOP_RECORDS.put(uid, shiDaoTopRecord);
                // 发送试道奖励
                if (serverService.getServer().getId() != 10000) {
                    fetchReward(role);
                } else {
                    // 通知登录服
                    try {
                        log.error("跨服试道结束发送称号等奖励=11={}", Json.toJson(shiDaoTopRecord, JsonFormat.compact()));
                        NutMap kuafuData = new NutMap();
                        kuafuData.put("content", Json.toJson(shiDaoTopRecord, JsonFormat.compact()));
                        List<LoginServer> list = SpringUtils.getBean(AccountService.class).queryServer();
                        log.error("线路列表=={}", Json.toJson(list, JsonFormat.compact()));
                        for (LoginServer server : list) {
                            Request request = Request.create(server.getUrl() + "/haitang/scl/my/kuafuReward", Request.METHOD.GET).setParams(kuafuData);
                            String content = Sender.create(request).setTimeout(2000).send().getContent();
                        }
                        log.error("跨服试道结束发送称号等奖励=={}", Json.toJson(shiDaoTopRecord, JsonFormat.compact()));
                    } catch (Exception e) {
                        log.error("奖励通知失败=={}=={}=={}", Json.toJson(shiDaoTopRecord, JsonFormat.compact()), e);
                    }

                }
            }
        }
        saveTopRecords();
    }

    public String getTitleName(int rank) {
        switch (rank) {
            case 1:
                if (serverService.getServer().getId() == 10000) {
                    return Const.TITLE_NAME_SHIDAO_FIRST_kuafu;
                }
                return Const.TITLE_NAME_SHIDAO_FIRST;
            case 2:
                if (serverService.getServer().getId() == 10000) {
                    return Const.TITLE_NAME_SHIDAO_SECOND_kuafu;
                }
                return Const.TITLE_NAME_SHIDAO_SECOND;
            case 3:
                if (serverService.getServer().getId() == 10000) {
                    return Const.TITLE_NAME_SHIDAO_THIRD_kuafu;
                }
                return Const.TITLE_NAME_SHIDAO_THIRD;
            default:
                return null;
        }
    }

    public void clearTopRecords(String levelRange) {
        List<Long> uids = new ArrayList<>();
        for (ShiDaoTopRecord shiDaoTopRecord : DataCache.SHI_DAO_TOP_RECORDS.values()) {
            if (levelRange.equals(shiDaoTopRecord.getLevelRange())) {
                uids.add(shiDaoTopRecord.getUid());
            }
        }
        for (long uid : uids) {
            DataCache.SHI_DAO_TOP_RECORDS.remove(uid);
        }

        saveTopRecords();
    }

    private void saveTopRecords() {
        Dao dao = SpringUtils.getBean(Dao.class);
        String data = JsonUtils.map2String(DataCache.SHI_DAO_TOP_RECORDS);
        dao.insertOrUpdate(new CommonFetchedData("shidao_top_records", data));
    }

    /**
     * 是否是月试道大会
     */
    private boolean isMonth(Calendar calendar) {
        return calendar.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
    }

    public void sendNotice() {
        if (shiDaoData == null) {
            return;
        }
        String str = shiDaoData.isMonthTao() ? "月道" : "总道";

        String notice = MessageFormat.format(NOTICE_CONTENT, str);
        SpringUtils.getChatService().sendSystem(notice, Const.BRODCAST_MSG_TYPE_ROLE);
    }

    /**
     * 领取试道大会奖励
     */
    public void fetchReward(Role role) {
        /**判断是否可以领取*/
//        TaskSet taskSet = SpringUtils.getTaskService().getTaskSet(REWARD_TASKID, role);
//        if (!SpringUtils.getTaskService().isTaskAccepted(role, taskSet)) {
//            return;
//        }
        if (StringUtils.isEmpty(role.getExtendBox().getShidaoRank())) {
            return;
        }

        /**给奖励*/

        /**内容格式：时间戳|等级|第几名*/
        String[] array = role.getExtendBox().getShidaoRank().split("\\|");

        byte rank = Byte.parseByte(array[2]);
        ShiDaoReward shiDaoReward = ActivityDataPool.shiDaoRewardMap.get(rank);

        /**判断包裹空间*/
//        if (!SpringUtils.getBean(BagService.class).checkBagEnough(role, false, shiDaoReward.getAttachments().size())) {
//            MessagePusher.notify2Player(role, I18nId.PMT_412);
//            return;
//        }

        role.getExtendBox().setShidaoRank(null);
        role.save();

        /**重置任务*/
        //TaskHelper.INSTANCE.getTaskHandler(TaskType.SHIDAO).forceResetTask(role, taskSet);

        send(role, rank, array[0], array[1]);
        MessagePusher.pushMessage(role, new RespNotifyMiscEx("试道奖励已经发送到#R邮件#n，请注意领取。"));
        log.error("试道大会结束后领取奖励=={}=={}=={}=={}=={}=={}", role.getRoleId(), role.getName(), rank, array[0], array[1]);
    }

    public void send(Role role, byte rank, String time, String level) {
        StringBuilder rewardDesc = new StringBuilder();

        Mail mail = SpringUtils.getMailService().createMail("试道第"+rank+"名奖励", "试道奖励", 7 * TimeUtil.ONE_DAY);
        ArrayList<NutMap> maps = new ArrayList<>();
        String reward = DataCache.REDIS_DATA.get("shidao_reward_" + rank);
        if(StringUtils.isNotEmpty(reward)){
            for (String s : reward.split("\\+")) {
                NutMap nutMap = DecodeSendMessage.buildSendRewardMessage(s);
                if(Const.rewardJinyuanbao == nutMap.getInt("type",0)){
                    int amount = Integer.parseInt(s.split("-")[1]);
                    rewardDesc.append("#R"+amount+"元宝");
                }
                maps.add(nutMap);
            }
            mail.getDatas().addAll(maps);
            SpringUtils.getMailService().sendNewMail(role, mail);
        }
        /**发系统消息*/
        String name = role.getName();
        String dateStr = TimeUtil.formatDate(new Date(Long.parseLong(time)), "yyyy年MM月dd日");
        String levelRange = getLevelRange(getRange(Short.parseShort(level)));
        String rankChinese = Const.ORDER_CHINESE.get((int) rank);
        String content = MessageFormat.format(REWARD_CONTENT, name, dateStr, levelRange, rankChinese, rewardDesc);
        SpringUtils.getChatService().sendSystem(content, Const.BRODCAST_MSG_TYPE_ROLE);
    }

    /**
     * 领取前三名每日奖励
     */
//    public void fetchDayReward(Role role) {
//        ShiDaoTopRecord shiDaoTopRecord = DataCache.SHI_DAO_TOP_RECORDS.get(role.getUid());
//        if (shiDaoTopRecord == null) {
//            MessagePusher.pushMessage(role, new RespNotifyMiscEx("你还不是试道前三名。"));
//            return;
//        }
//        if (shiDaoTopRecord.isDayRewardFetch()) {
//            MessagePusher.pushMessage(role, new RespNotifyMiscEx("今日奖励已领取明日再来。"));
//            return;
//        }
//
//        shiDaoTopRecord.setDayRewardFetch(true);
//        saveTopRecords();
//
//        int siver = getRewardSiver(shiDaoTopRecord.getRank());
//        if (siver > 0) {
//            SpringUtils.getRoleService().addSiver(role, siver, Reason.SHIDAO_DAY_REWARD);
//            String content = String.format("你领取了#R%s#n银元宝。", siver);
//            MessagePusher.pushMessage(role, new RespNotifyMiscEx(content));
//        }
//    }


    /**
     * 每日重置
     */
    public void dailyReset(Role role) {
        ShiDaoTopRecord shiDaoTopRecord = DataCache.SHI_DAO_TOP_RECORDS.get(role.getUid());
        if (shiDaoTopRecord == null) {
            return;
        }

        shiDaoTopRecord.setDayRewardFetch(false);
        saveTopRecords();
    }

    public int getStartH() {
        return startH;
    }

    public void setStartH(int startH) {
        this.startH = startH;
    }

    public int getStartM() {
        return startM;
    }

    public void setStartM(int startM) {
        this.startM = startM;
    }

    public void kuafuShidao() {
        String aaaa = DateUtils.dayForWeek(new Date());
        if (serverService.getServer().getId() == 10000) {
            if (aaaa.equals("7")) {
                // 通知游戏服
                String content = "20##00";
                Map<String, Object> params = new HashMap<>();
                params.put("content", content);
                try {
                    List<LoginServer> list = SpringUtils.getBean(AccountService.class).queryServer();
                    log.error("线路列表=={}", Json.toJson(list, JsonFormat.compact()));
                    for (LoginServer server : list) {
                        Request request = Request.create(server.getUrl() + "/haitang/scl/my/startKuafu", Request.METHOD.POST).setParams(params);
                        Sender.create(request).setTimeout(2000).send();
                    }
                    SpringUtils.getBean(PlayerService.class).delKuafuRole();
                    setStartM(00);
                    setStartH(20);
                    prepareOnceShiDao();
                } catch (Exception e) {
                    log.error("开启跨服试道失败", e);
                }
            }
        }
    }

    public void notifyShidao() {
        String aaaa = DateUtils.dayForWeek(new Date());
        if (aaaa.equals("8")) {
            String notice = "本次跨服试道大会将于#R晚上20:50开启#n，恭候各位道友准时降临跨服试道专线（请先找#R跨服赛事接引人申请#n，然后进入#R选区界面#n，进入#R跨服专线#n，参加跨服试道）！#51 #82";
            SchedulerManager.getInstance().schedule(new Runnable() {
                @Override
                public void run() {
                    chatService.sendAdnotice(notice);
                }
            }, 30000);
            for (int i = 0; i < 11; i++) {
                SchedulerManager.getInstance().schedule(new Runnable() {
                    @Override
                    public void run() {
                        chatService.sendAdnotice(notice);
                    }
                }, 60000 * (i + 1) * 5);
            }
            return;
        }
        /*修改试道开启时间 和周几      */
//        if (!aaaa.equals("2")&& !aaaa.equals("4")&& !aaaa.equals("6")) {
//            return;
//        }
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
        int min = calendar.get(Calendar.MINUTE);
        setStartM(min);/*几分*/
        setStartH(hour);/*几点*/
        prepareOnceShiDao();
        String mmin = "";
        if(min <= 9){
            mmin =  "0" + min ;
        }else{
            mmin = String.valueOf(min);
        }
        String finalMmin = mmin;
        SchedulerManager.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                String notice = "本次试道大会已于#R"+hour+":"+ finalMmin +"开启#n，各位道友现在就可以降临试道场等待活动了！#51 #82";
                chatService.sendAdnotice(notice);
            }
        }, 1000);
        for (int i = 0; i < 3; i++) {
            SchedulerManager.getInstance().schedule(new Runnable() {
                @Override
                public void run() {
                    String notice = "本次试道大会已于#R"+hour+":"+finalMmin+"开启#n，各位道友现在就可以降临试道场等待活动了！#51 #82";
                    chatService.sendAdnotice(notice);
                }
            }, 60000 * (i + 1));
        }
    }
}
